/* 前端项目性能检测策略类主文件 */
// 静态资源策略模块
const SrImgStrategy = require('./srImg');
const SrHtmlStrategy = require('./srHtml');
const SrCssStrategy = require('./srCss');
const SrJsStrategy = require('./srJs');
const SrTsStrategy = require('./srTs');

// 框架特定文件检测策略模块
const FwVueStrategy = require('./fwVue');
const FwReactStrategy = require('./fwReact');

// 该策略类为引用类，所以错误向外抛出
class Strategy {
  /**
   * 构造函数
   * @param {*} params 示例：
   * {
   *   img: [{}],
   *   html: [{}],
   *   css: [{}],
   *   js: [{}],
   *   ts: [{}],
   *   json: [{}],
   *   vue: [{}],
   *   react: [{}]
   * }
   */
  constructor(params = {}) {
    // 临时文件序号递增
    this._fileIndex = 0;
    // 图片文件列表
    this._imgList = [];
    // html文件列表
    this._htmlList = [];
    // css文件列表
    this._cssList = [];
    // js文件列表
    this._jsList = [];
    // ts文件列表
    this._tsList = [];
    // json文件列表
    this._jsonList = [];
    // vue文件列表
    this._vueList = [];
    // react文件列表
    this._reactList = [];
    this._init(params);
  }

  // 初始化方法
  _init(params) {
    this._fileIndex = 0;
    this.validAndAssignParams(params);
  }

  // 校验并赋值传参
  validAndAssignParams(params) {
    Object.keys(params).forEach(key => {
      const val = params[key];
      if (!Array.isArray(val)) {
        throw new Error(`Strategy类入参params-key: ${key}, value: ${val} 非数组，请调用方检查入参是否正确`);
      }
      if (val.length) {
        this[`_${key}List`] = val;
      }
    });
  }

  // 执行策略
  execute(extra, cb = null) {
    if (this._vueList.length) {
      // vue框架策略
      // 1.先执行vue框架特定资源检测策略
      FwVueStrategy.execute(this._vueList, {
        ...extra,
        index: ++this._fileIndex
      }, () => {
        // 2.再执行静态资源策略
        this._executeSrStrategy(extra, () => {
          cb && cb();
        });
      });
    } else if (this._reactList.length) {
      // react框架策略
      // 1.先执行react框架特定资源检测策略
      FwReactStrategy.execute(this._reactList, {
        ...extra,
        index: ++this._fileIndex
      }, () => {
        // 2.再执行静态资源策略
        this._executeSrStrategy(extra, () => {
          cb && cb();
        });
      });
    } else {
      // 非框架策略
      // 1.执行静态资源策略后直接回调
      this._executeSrStrategy(extra, () => {
        cb && cb();
      });
    }
  }

  // 执行静态资源策略
  _executeSrStrategy(extra, cb = null) {
    // 单线程执行，只能同步操作
    // 1.静态资源-图片
    SrImgStrategy.execute(this._imgList, {
      ...extra,
      index: ++this._fileIndex
    }, () => {
      // 2.静态资源-HTML
      SrHtmlStrategy.execute(this._htmlList, {
        ...extra,
        cssList: this._cssList,
        index: ++this._fileIndex
      }, () => {
        // 3.静态资源-CSS
        SrCssStrategy.execute(this._cssList, {
          ...extra,
          index: ++this._fileIndex
        }, () => {
          // 4.静态资源-JS
          SrJsStrategy.execute(this._jsList, {
            ...extra,
            index: ++this._fileIndex
          }, () => {
            // 5.静态资源-TS
            SrTsStrategy.execute(this._tsList, {
              ...extra,
              index: ++this._fileIndex
            }, () => {
              // 静态资源所有策略执行完后回调
              cb && cb();
            });
          });
        });
      });
    });
    // 2.多线程执行 - TODO
  }
}

module.exports = Strategy;
